import axios, { InternalAxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, AxiosError } from 'axios'
import router from '@/router'
import { IResponseData } from '@/request/base'
import { ElMessage, ElLoading } from 'element-plus'
import { LoadingInstance } from 'element-plus/lib/components/loading/src/loading.js'
import { config } from '@/request/httpBaseUrl'

type TAxiosOption = {
  baseURL: string;
  timeout: number;
}


let loading: LoadingInstance;
let loginSate: boolean;
class Http {
  // service: AxiosInstance;
  service;
  constructor(config: TAxiosOption) {
    this.service = axios.create(config)
    loginSate = true
    /* 请求拦截  this.service.interceptors.request.use(config => config, error => Promise.reject(error))*/
    this.service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
      /* 业务逻辑
      1. 开启全屏loading动画
      2. 数据加密config.data
      3. 请求头加上token，结合vuex或localstorage：
          if(store.getters.token) config.headers['x-token'] = store.getters.token
          else 重定向
      4. ……
      */
      loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.7)',
      })

      if (localStorage.getItem('token')) {
        (config.headers as AxiosRequestHeaders).token = localStorage.getItem('token') as string
      }

      return config
    }, (error: AxiosError) => {
/* 请求错误 
      1. 关闭全屏loading动画
      2. 重定向到错误页
      */
        loading.close()
      // 处理 HTTP 网络错误
      let msg = '';
      const status = error.response?.status; // HTTP响应状态码
      switch (status) {
        case 404:
          msg = '请求路径错误-404';
          break;
        case 500:
          msg = '服务端错误-500';
          break;
        default:
          msg = '请求错误';
      }
      ElMessage.error(msg);
      return Promise.reject(error);
    })


    /* 响应拦截   this.service.interceptors.response.use(response => response.data, error => Promise.reject(error))*/
    this.service.interceptors.response.use((response: AxiosResponse) => {
      /* 
      1. 关闭全屏loading动画
      2. 数据解密
      3. 根据 response.data.code 做不同的错误处理
      4. ……
      */
      loading.close()


      const data = response.data
      const { code } = data

      // 如果没有登陆则返回登录页面
      if(code === 9999){
        if(loginSate){
          ElMessage.error("账户未登录")
          loginSate = false
        }
         router.replace("/login");
         return Promise.reject(data.msg)
      } else {
        loginSate = true
      }
      // 没有接口权限
      if(code === 9001 || code === 9005){
        ElMessage.error(data.msg)
        router.replace("/");
        return Promise.reject(data.msg)
      }

      if (code !== 2000) {
        ElMessage.error(data.msg)
        return Promise.reject(data.msg)
        
      }
      return response.data
    }, error => {
      loading.close()
      ElMessage.error('请求失败',)
      return Promise.reject(error)
    })
  }
  get<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
        return this.service.get(url, { params, ..._object })
  }
  post<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
    return this.service.post(url, params, _object)
  }
  put<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
    return this.service.put(url, params, _object)
  }
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  delete<T>(url: string, params?: any, _object = {}): Promise<IResponseData<T>> {
    return this.service.delete(url, { params, ..._object })
  }
}

export default new Http(config)
